// ==UserScript==
// @name         华医网系列脚本-检测页面状态登录OR学习（精准检测版）
// @namespace    http://tampermonkey.net/
// @version      3.3
// @description  精准检测继续学习按钮，找到则鼠标移动点击，未找到弹窗提示
// @author       leng
// @match        https://cme28.91huayi.com/cme/index.html
// @match        https://www.91huayi.com/
// @match        https://www.91huayi.com/index.html
// @match        https://cme28.91huayi.com/pages/cme.aspx
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // 日志工具（精简且清晰）
    const logger = {
        info: (msg) => console.log(`[华医网脚本][INFO] ${new Date().toLocaleTimeString()} - ${msg}`),
        success: (msg) => console.log(`[华医网脚本][SUCCESS] ${new Date().toLocaleTimeString()} - ${msg}`),
        error: (msg) => console.error(`[华医网脚本][ERROR] ${new Date().toLocaleTimeString()} - ${msg}`)
    };

    // 页面URL常量
    const LOGIN_PAGE = 'https://cme28.91huayi.com/cme/index.html';
    const STUDY_PAGE = 'https://cme28.91huayi.com/pages/cme.aspx';

    // -------------------------- 核心工具函数 --------------------------
    /**
     * 计算元素中心点坐标（考虑页面滚动偏移）
     * @param {HTMLElement} elem - 目标元素
     * @returns {Object} 包含x和y坐标的对象
     */
    function getElementCenter(elem) {
        const rect = elem.getBoundingClientRect();
        return {
            x: rect.left + rect.width / 2 + window.scrollX,
            y: rect.top + rect.height / 2 + window.scrollY
        };
    }

    /**
     * 模拟鼠标移动到指定坐标
     * @param {number} x - 目标X坐标
     * @param {number} y - 目标Y坐标
     */
    function simulateMouseMove(x, y) {
        const moveEvent = new MouseEvent('mousemove', {
            clientX: x - window.scrollX,
            clientY: y - window.scrollY,
            screenX: x,
            screenY: y,
            bubbles: true,
            cancelable: true,
            view: window
        });
        document.dispatchEvent(moveEvent);
        logger.info(`鼠标已移动到坐标：(${Math.round(x)}, ${Math.round(y)})`);
    }

    /**
     * 精准查找元素（仅匹配指定特征，避免误判）
     * @param {string} selector - 目标元素CSS选择器
     * @param {string} elementDesc - 元素描述（用于日志）
     * @returns {HTMLElement|null} 匹配元素或null
     */
    function preciseFindElement(selector, elementDesc) {
        const elem = document.querySelector(selector);
        if (elem) {
            // 二次校验：确保元素可见（避免隐藏元素误判）
            const isVisible = window.getComputedStyle(elem).display !== 'none' &&
                              window.getComputedStyle(elem).visibility !== 'hidden';
            if (isVisible) {
                logger.success(`找到${elementDesc}（元素状态：可见）`);
                return elem;
            }
            logger.info(`${elementDesc}已找到但处于隐藏状态，跳过`);
            return null;
        }
        logger.info(`未找到${elementDesc}`);
        return null;
    }

    /**
     * 模拟真实点击（鼠标移动到元素后点击，确保触发页面有效响应）
     * @param {HTMLElement} elem - 目标元素
     * @param {string} elemDesc - 元素描述
     */
    function simulateEffectiveClick(elem, elemDesc) {
        if (!elem) return;
        
        // 1. 获取元素中心点坐标
        const { x, y } = getElementCenter(elem);
        
        // 2. 模拟鼠标移动到元素
        simulateMouseMove(x, y);
        
        // 3. 移动后停顿100ms（模拟人工定位）
        setTimeout(() => {
            // 4. 触发鼠标悬停
            elem.dispatchEvent(new MouseEvent('mouseover', { bubbles: true, cancelable: true }));
            
            // 5. 悬停后停顿150ms（模拟停留）
            setTimeout(() => {
                // 6. 模拟按下鼠标
                elem.dispatchEvent(new MouseEvent('mousedown', {
                    clientX: x - window.scrollX,
                    clientY: y - window.scrollY,
                    bubbles: true,
                    cancelable: true,
                    button: 0 // 左键
                }));
                
                // 7. 按下后停顿100ms（模拟按压）
                setTimeout(() => {
                    // 8. 模拟松开鼠标并触发点击
                    elem.dispatchEvent(new MouseEvent('mouseup', {
                        clientX: x - window.scrollX,
                        clientY: y - window.scrollY,
                        bubbles: true,
                        cancelable: true,
                        button: 0
                    }));
                    elem.dispatchEvent(new MouseEvent('click', {
                        clientX: x - window.scrollX,
                        clientY: y - window.scrollY,
                        bubbles: true,
                        cancelable: true,
                        view: window,
                        button: 0
                    }));
                    logger.success(`已成功移动并点击【${elemDesc}】`);
                }, 100);
            }, 150);
        }, 100);
    }

    /**
     * 页面完全加载后执行（确保DOM和资源就绪）
     * @param {Function} callback - 回调函数
     */
    function onPageFullyReady(callback) {
        if (document.readyState === 'complete') {
            logger.info('当前页面已完全加载');
            callback();
        } else {
            const loadHandler = () => {
                logger.info('当前页面加载完成');
                callback();
                window.removeEventListener('load', loadHandler);
            };
            window.addEventListener('load', loadHandler);
        }
    }

    // -------------------------- 核心业务逻辑 --------------------------
    /**
     * 检测并处理“继续学习”按钮
     * 规则：匹配 value="继续学习" + class="btn67"，找到则点击，未找到弹窗提示
     */
    function handleContinueStudyBtn() {
        logger.info('开始检测“继续学习”按钮（匹配：value="继续学习" + class="btn67"）');
        // 精准选择器：同时匹配value属性和class，避免误判其他按钮
        const continueSelector = 'input.btn67[value="继续学习"]';
        const continueBtn = preciseFindElement(continueSelector, '继续学习按钮');

        if (continueBtn) {
            simulateEffectiveClick(continueBtn, '继续学习按钮');
        } else {
            logger.error('未检测到“继续学习”按钮（需满足：class="btn67" 且 value="继续学习"）');
            // 弹窗提示：明确引导用户操作
            alert('⚠️ 请自行选择学习课程\n提示：在当前页面找到并点击“继续学习”按钮（通常为蓝色或绿色按钮，标注“继续学习”字样）');
        }
    }

    /**
     * 检测登录按钮并点击
     */
    function handleLoginBtn() {
        const loginSelector = '#ssologin, #btn_login_header, #btn_login_area';
        const loginBtn = preciseFindElement(loginSelector, '登录按钮');
        if (loginBtn) {
            simulateEffectiveClick(loginBtn, '登录按钮');
            return true;
        }
        return false;
    }

    /**
     * 检测退出按钮并跳转学习页
     */
    function handleLogoutAndJump() {
        const logoutSelector = 'input.exit_btn[value="退出登录"]';
        const logoutBtn = preciseFindElement(logoutSelector, '退出按钮');
        if (logoutBtn) {
            logger.info('检测到退出按钮，跳转至学习页面');
            window.location.href = STUDY_PAGE;
            // 跳转后处理“继续学习”按钮
            onPageFullyReady(handleContinueStudyBtn);
            return true;
        }
        return false;
    }

    // -------------------------- 主流程控制 --------------------------
    function main() {
        logger.info('===== 华医网脚本启动 =====');
        const currentUrl = window.location.href;

        // 1. 若在学习页，直接检测“继续学习”按钮
        if (currentUrl === STUDY_PAGE) {
            onPageFullyReady(handleContinueStudyBtn);
            return;
        }

        // 2. 其他页面：先跳转登录页
        if (currentUrl !== LOGIN_PAGE) {
            logger.info(`自动跳转到登录页面：${LOGIN_PAGE}`);
            window.location.href = LOGIN_PAGE;
            // 登录页加载完成后执行后续操作
            onPageFullyReady(async () => {
                const loginSuccess = handleLoginBtn();
                if (!loginSuccess) {
                    logger.info('未找到登录按钮，尝试检测退出按钮');
                    await handleLogoutAndJump();
                }
            });
        } else {
            // 3. 已在登录页：直接检测登录/退出按钮
            onPageFullyReady(async () => {
                const loginSuccess = handleLoginBtn();
                if (!loginSuccess) {
                    await handleLogoutAndJump();
                }
            });
        }
    }

    // 启动脚本
    main();
})();